<?php
/**
 * Smithy PHP library
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * Smithy is a free Zend Framework based PHP library.
 *
 * @category   Smithy
 * @package    Smithy_Model
 * @subpackage RecordSet
 * @copyright  Copyright (c) 2008-2009 Kovács Tamás
 * @license    New BSD License
 * @version    $Id: Abstract.php ktamas $
 */


/**
 * A basic collection for value objects.
 *
 * @author      Kovács Tamás
 * @category    Smithy
 * @package     Smithy_Model
 * @subpackage  Collection
 * @version     2.0
 */
abstract class Smithy_Model_Collection_Abstract implements Iterator //IteratorAggregate, Countable
{
    /**
     * The model gateway.
     *
     * @var Smithy_Model_Gateway_Abstract
     */
    protected $_gateway = null;

    /**
     * The collection object.
     *
     * @var IteratorAggregate|Iterator|Countable
     */
    protected $_collection = null;

    /**
     * The iterator of the collection.
     *
     * @var Iterator
     */
    protected $_collectionIterator = null;

    /**
     * The type of the entity objects, contained by the collection.
     *
     * @var string
     */
    protected $_entityClass = null;


    /**
     * Constructor
     *
     * @param IteratorAggregate|Iterator|Countable|null $collection [OPTIONAL]
     * @param Smithy_Model_Gateway_Abstract $gateway [OPTIONAL]
     * @return void
     */
    public function __construct($collection = null, Smithy_Model_Gateway_Abstract $gateway = null)
    {
        $this->_gateway = $gateway;
        $this->setCollection($collection);
        $this->init();
    }

    /**
     * Initialize collection.
     *
     * @return void
     */
    public function init()
    {}

    /**
     * Sets the collections and the collection iterator.
     *
     * @param IteratorAggregate|Iterator|Countable|null $collection
     * @return Smithy_Model_Collection_Abstract Provides fluent interface.
     * @throws Smithy_Model_Collection_Exception If invalid collection is provided.
     */
    public function setCollection($collection)
    {
        if (null === $collection) {
            $collection = array();
        }
        $this->_collection = $collection;

        if ($collection instanceof IteratorAggregate) {
            $this->_collectionIterator = $this->_collection->getIterator();
        } else if ($collection instanceof Iterator) {
            $this->_collectionIterator = $this->_collection;
        } else if (is_array($this->_collection))  {
            $this->_collectionIterator = new ArrayIterator($this->_collection);
        } else {
            throw new Smithy_Model_Collection_Exception('Invalid collection provided. ');
        }

        return $this;
    }

    /**
     * Returns the gateway object.
     *
     * @return Smithy_Model_Gateway_Abstract
     */
    public function getGateway()
    {
        return $this->_gateway;
    }

    /**
     * Returns the current element.
     *
     * @see Iterator::current()
     * @return null|Smithy_Model_Entity_Abstract
     */
    public function current ()
    {
        return $this->createEntity(
            $this->_collectionIterator->current()
        );
    }

    /**
     *
     * @see Iterator::key()
     */
    public function key ()
    {
        return $this->_collectionIterator->key();
    }

    /**
     *
     * @see Iterator::next()
     */
    public function next ()
    {
        return $this->_collectionIterator->next();
    }

    /**
     *
     * @see Iterator::rewind()
     */
    public function rewind ()
    {
        return $this->_collectionIterator->rewind();
    }

    /**
     *
     * @see Iterator::valid()
     */
    public function valid ()
    {
        return $this->_collectionIterator->valid();
    }

    /**
     *
     * @see Countable::count()
     */
    public function count ()
    {
        return $this->_collectionIterator->count();
    }

    /**
     * Creates an entity object using the gateway.
     *
     * @param array|Doctrine_Record $data
     * @return Smithy_Model_Entity_Abstract
     */
    public function createEntity($data)
    {
        return $this->getGateway()->createEntity($data);
    }
}
